<template>
  <div>
    <!-- 面包屑导航 -->
    <el-breadcrumb separator-class="el-icon-arrow-right">
      <el-breadcrumb-item :to="{ path: '/home' }">首页</el-breadcrumb-item>
      <el-breadcrumb-item>商品管理</el-breadcrumb-item>
      <el-breadcrumb-item>参数列表</el-breadcrumb-item>
    </el-breadcrumb>
    <el-card class="box-card">
      <!-- 头部的警告 -->
      <el-alert title="注意：值允许第三级分类设置的相关属性" type="warning" show-icon :closable="false"> </el-alert>
      <!-- 选择商品分类区域 -->
      <el-row class="cat_opt">
        <el-col>
          <span>选择商品分类:</span>
          <!-- 选择级联 -->
          <el-cascader v-model="returnParamsId" :options="cateList" :props="propsParam" @change="handleChange"> </el-cascader>
        </el-col>
      </el-row>
      <!-- 标签页 -->
      <el-tabs v-model="activeName" @tab-click="handleTabClick">
        <el-tab-pane label="动态参数" name="many">
          <!-- 添加动态参数的面板 -->
          <el-button type="primary" size="mini" :disabled="isDisabled" @click="manyDialogVisible = true">添加参数</el-button>
          <!-- 动态参数的表单 -->
          <el-table border :data="manyTableData">
            <!-- 展开行 -->
            <el-table-column type="expand">
              <template slot-scope="scope">
                <el-tag class="tag" v-for="(item, i) in scope.row.attr_vals" :key="i" closable @close="tagClose(i, scope.row)">
                  {{ item }}
                </el-tag>
                <!--在引入这个新增的tag标签的时候 会有一个bug：就是点击的是一个新增的数据，下面那个展开行也会跟着一起操作 -->
                <!-- 原因：这个组件他们共用的都一个inputVisible和 inputValue-->
                <!-- 解决：在js中循环渲染tag的时候 添加inputVisible和 inputValue，然后这里的v-if和v-model通过row绑定js里传来的数据 -->
                <!-- 然后在本身的el-button的点击事件里把inputVisible和 inputValue删了 -->
                <el-input class="input-new-tag" v-if="scope.row.inputVisible" v-model="scope.row.inputValue" ref="saveTagInput" size="small" @keyup.enter.native="handleInputConfirm(scope.row)" @blur="handleInputConfirm(scope.row)"> </el-input>
                <el-button v-else class="button-new-tag" size="small" @click="showInput(scope.row)">+ New Tag</el-button>
              </template>
            </el-table-column>
            <!-- 索引列 -->
            <el-table-column type="index" label="#"></el-table-column>
            <el-table-column prop="attr_name" label="参数名称"></el-table-column>
            <el-table-column label="操作">
              <template slot-scope="scope">
                <!-- 修改按钮 -->
                <el-button type="primary" icon="el-icon-edit" size="mini" @click="editShow(scope.row.attr_id)"></el-button>
                <!-- 删除按钮 -->
                <el-button type="danger" icon="el-icon-delete" size="mini" @click="deleteFrom(scope.row)"></el-button>
              </template>
            </el-table-column>
          </el-table>
        </el-tab-pane>

        <!-- 静态的表单 -->
        <el-tab-pane label="静态属性" name="only">
          <!-- 添加静态属性的面板 -->
          <el-button type="primary" size="mini" :disabled="isDisabled" @click="manyDialogVisible = true">添加属性</el-button>
          <!-- 静态参数的表单 -->
          <el-table border :data="onlyTableData">
            <!-- 展开行 -->
            <el-table-column type="expand">
              <template slot-scope="scope">
                <el-tag class="tag" v-for="(item, i) in scope.row.attr_vals" :key="i" closable @close="tagClose(i, scope.row)">
                  {{ item }}
                </el-tag>
                <!--在引入这个新增的tag标签的时候 会有一个bug：就是点击的是一个新增的数据，下面那个展开行也会跟着一起操作 -->
                <!-- 原因：这个组件他们共用的都一个inputVisible和 inputValue-->
                <!-- 解决：在js中循环渲染tag的时候 添加inputVisible和 inputValue，然后这里的v-if和v-model通过row绑定js里传来的数据 -->
                <!-- 然后在本身的el-button的点击事件里把inputVisible和 inputValue删了 -->
                <el-input class="input-new-tag" v-if="scope.row.inputVisible" v-model="scope.row.inputValue" ref="saveTagInput" size="small" @keyup.enter.native="handleInputConfirm(scope.row)" @blur="handleInputConfirm(scope.row)"> </el-input>
                <el-button v-else class="button-new-tag" size="small" @click="showInput(scope.row)">+ New Tag</el-button>
              </template>
            </el-table-column>
            <!-- 索引列 -->
            <el-table-column type="index" label="#"></el-table-column>
            <el-table-column prop="attr_name" label="属性名称"></el-table-column>
            <el-table-column label="操作">
              <template slot-scope="scope">
                <el-button type="primary" icon="el-icon-edit" size="mini" @click="editShow(scope.row.attr_id)"></el-button>
                <el-button type="danger" icon="el-icon-delete" size="mini" @click="deleteFrom(scope.row.attr_id)"></el-button>
              </template>
            </el-table-column>
          </el-table>
        </el-tab-pane>
      </el-tabs>
      <!-- 添加参数的对话框 -->

      <el-dialog :title="'添加' + tittleText" :visible.sync="manyDialogVisible" width="50%" @close="addDialogClose">
        <!-- 表单 -->
        <el-form :model="manyRuleForm" :rules="manyRules" ref="manyRuleForm" label-width="100px">
          <el-form-item :label="tittleText" prop="name">
            <el-input v-model="manyRuleForm.name"></el-input>
          </el-form-item>
        </el-form>
        <span slot="footer" class="dialog-footer">
          <el-button @click="manyDialogVisible = false">取 消</el-button>
          <el-button type="primary" @click="submitAddMany">确 定</el-button>
        </span>
      </el-dialog>
      <!--  -->
      <!-- 修改对话框 -->
      <el-dialog :title="'修改' + tittleText" :visible.sync="eidtDialogVisible" width="50%" @close="eidtDialogClose">
        <!-- 表单 -->
        <el-form :model="editRuleForm" :rules="editRules" ref="editRuleForm" label-width="100px">
          <el-form-item :label="tittleText" prop="name">
            <el-input v-model="editRuleForm.name"></el-input>
          </el-form-item>
        </el-form>
        <span slot="footer" class="dialog-footer">
          <el-button @click="eidtDialogVisible = false">取 消</el-button>
          <el-button type="primary" @click="editFromBtn">确 定</el-button>
        </span>
      </el-dialog>
      <!--  -->
    </el-card>
  </div>
</template>
<script>
export default {
  data() {
    return {
      // 分类的数据
      cateList: [],
      // 返回的选中级联的id
      returnParamsId: [],
      // props 的配置项
      propsParam: {
        expandTrigger: "hover",
        value: "cat_id",
        label: "cat_name",
        children: "children"
      },
      // 被激活的页签名称
      activeName: "many",
      // 动态参数的数据
      manyTableData: [],
      // 静态参数的数据
      onlyTableData: [],
      // 控制动态添加参数的
      manyDialogVisible: false,
      // 控制动静态添加参数的
      onlyDialogVisible: false,
      // 添加动态参数的表单
      manyRuleForm: {
        name: ""
      },
      //  动态表单的验证规则
      manyRules: {
        name: [
          { required: true, message: "请输入参数名称", trigger: "blur" },
          { min: 2, max: 15, message: "长度在 2 到 15 个字符", trigger: "blur" }
        ]
      },
      // 修改对话框的控制按钮
      eidtDialogVisible: false,
      // 修改对话框的表单
      editRuleForm: {
        name: ""
      },
      //  修改对话表单的验证规则
      editRules: {
        name: [
          { required: true, message: "请输入参数名称", trigger: "blur" },
          { min: 2, max: 15, message: "长度在 2 到 15 个字符", trigger: "blur" }
        ]
      },
      // tag标签的input 和button的切换
      inputVisible: false,
      inputValue: ""
    }
  },
  created() {
    this.getCateList()
  },
  computed: {
    // 控制添加参数或者属性的按钮是否显示
    isDisabled() {
      //根据那个selset返回的数组的长度 我们就可以判断是否有无
      // 如果按钮需要被禁用，则返回true，否则返回false
      if (this.returnParamsId.length === 0) {
        return true
      } else {
        return false
      }
    },
    // 动态添加参数的标题文本
    tittleText() {
      if (this.activeName == "many") {
        return "动态参数"
      } else {
        return "静态属性"
      }
    }
  },
  methods: {
    async getCateList() {
      var { data: res } = await this.$http.get("categories")
      if (res.meta.status !== 200) return this.$message.error("获取分类数据列表失败")
      this.cateList = res.data
      console.log(this.cateList)
    },
    // 当级联有变动的时候代用这个函数
    async handleChange() {
      console.log(this.returnParamsId)
      this.getCategories()
    },
    // tab页签 点击事件的处理函数
    async handleTabClick() {
      console.log(this.activeName)
      // 获取父级的id
      if (this.returnParamsId.length == 0) {
        return this.$message.info("请选择要获取的参数")
      } else {
        this.getCategories()
      }
    },
    // 获取动态或者静态的接口
    async getCategories() {
      var id = this.returnParamsId[this.returnParamsId.length - 1]
      let { data: res } = await this.$http.get("categories/" + id + "/attributes", { params: { sel: this.activeName } })
      if (res.meta.status !== 200) return this.$message.error("获取动态参数列表失败")
      // 渲染tag标签需要用到数组，但是这里的attr_vals是字符串 ，需要转换
      res.data.forEach(item => {
        //1：这里bug处理 我们需要三元判断，如果不的话，当我们新增的动态参数展开行理应
        // 是没有tag标签的，但是实际上会有，这是因为我们新增加的参数的 attr_vals按照split下来是一个[""]
        // 会显示一个空的tag标签，我们不想要这个tag标签那么这样写：
        // item.attr_vals = item.attr_vals.split(" ")
        console.log(item.attr_vals)
        item.attr_vals = item.attr_vals ? item.attr_vals.split(" ") : []
        //:2bug：在处理后面的tag的新增点击btn男变为input表单的时候有个bug：就是点一个展开
        // 行输入的值会和下一行的新增内容联系到一起，我们明明想操作一个却同时操作了两个
        // 应该：
        item.inputVisible = false
        item.inputValue = ""
        console.log(item.attr_vals)
      })

      console.log(res.data)
      //转换之后res.data.attr_vals 就不是字符串了，是一个数组 我们html中可以
      // 通过scop拿到 attr_vals 在动态的展开行里 数据进行渲染成tag标签

      // 我们需要判断获取的res.data 是 动态 还是 静态 的数据 然后分别存起来
      if (this.activeName == "many") {
        this.manyTableData = res.data
      } else {
        this.onlyTableData = res.data
      }
    },
    // tag标签里按下 之后由btn变为input
    showInput(row) {
      row.inputVisible = true
      // $nextTick函数的作用，当页面的dom元素被重新渲染，才会指定回调这个函数里的代码
      this.$nextTick(_ => {
        this.$refs.saveTagInput.$refs.input.focus()
      })
    },
    // tag标签里的input的添加 失去焦点 或者按回车都会完成添加触发这个函数
    async handleInputConfirm(row) {
      if (row.inputValue.trim().length === 0) {
        row.inputValue = ""
        row.inputVisible = false
        return
      } else {
        row.attr_vals.push(row.inputValue)
        var id = this.returnParamsId[this.returnParamsId.length - 1]
        const { data: res } = await this.$http.put("categories/" + id + "/attributes/" + row.attr_id, {
          attr_name: row.attr_name,
          attr_sel: row.attr_sel,
          attr_vals: row.attr_vals.join(" ")
        })
        if (res.meta.status !== 200) return this.$message.error("操作失败")
        this.$message.success("成功添加")
        row.inputValue = ""
        row.inputVisible = false
      }

      // this.inputVisible = false
      // this.inputValue = ""
      // 这里需要干掉，因为操作一个会联系到两个的操作
    },
    // 点击动态添加的按钮
    async submitAddMany() {
      this.$refs.manyRuleForm.validate(async valid => {
        if (!valid) {
          return
        } else {
          var id = this.returnParamsId[this.returnParamsId.length - 1]
          var { data: res } = await this.$http.post("categories/" + id + "/attributes", { attr_name: this.manyRuleForm.name, attr_sel: this.activeName })
          if (res.meta.status !== 201) return this.$message.error("添加参数失败")
          this.$message.success("添加参数成功")
          console.log(res.data)
          this.getCategories()
          this.manyDialogVisible = false
        }
      })
    },
    // tag 便签的删除
    async tagClose(i, row) {
      row.attr_vals.splice(i, 1)
      this.saveDelete(row)
    },
    // 关闭对话框清除文本值
    addDialogClose() {
      this.$refs.manyRuleForm.resetFields()
    },
    // 修改对话框的关闭清空文本值
    eidtDialogClose() {
      this.$refs.editRuleForm.resetFields()
    },
    // 渲染修改对话框
    async editShow(atid) {
      var id = this.returnParamsId[this.returnParamsId.length - 1]
      console.log(id, atid)
      var { data: res } = await this.$http.get("categories/" + id + "/attributes/" + atid, { params: { attr_sel: this.activeName } })
      console.log(res)
      if (res.meta.status !== 200) return this.$message.error("获取失败")
      this.editRuleForm.name = res.data.attr_name
      this.editRuleForm.attr_id = atid
      this.eidtDialogVisible = true
    },

    // 修改对话框的确认按钮
    editFromBtn() {
      this.$refs.editRuleForm.validate(async valid => {
        if (!valid) return

        console.log(this.editRuleForm.name)
        console.log(this.activeName)
        var id = this.returnParamsId[this.returnParamsId.length - 1]
        var { data: res } = await this.$http.put("categories/" + id + "/attributes/" + this.editRuleForm.attr_id, {
          attr_name: this.editRuleForm.name,
          attr_sel: this.activeName
        })
        console.log(res)
        if (res.meta.status !== 200) return this.$message.error("修改失败")
        this.$message.success("修改成功")
        this.getCategories()
        this.eidtDialogVisible = false
      })
    },
    // 删除对话框
    async deleteFrom(row) {
      const result = await this.$confirm("此操作将永久删除该文件, 是否继续?", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning"
      }).catch(error => error)
      if (result !== "confirm") return this.$message.info("取消了操作")
      this.saveDelete(row) //调用删除接口的函数
      this.getCategories()
    },
    // 封装删除接口函数
    async saveDelete(row) {
      var id = this.returnParamsId[this.returnParamsId.length - 1]
      var { data: res } = await this.$http.delete("categories/" + id + "/attributes/" + row.attr_id)
      if (res.meta.status !== 200) return this.$message.error("删除失败")
      this.$message.success("删除成功")
    }
  }
}
</script>
<style scoped>
.cat_opt {
  margin: 15px 0;
}
.tag {
  margin-right: 10px;
}
.el-tag + .el-tag {
  margin-left: 10px;
}
.button-new-tag {
  margin-left: 10px;
  height: 32px;
  line-height: 30px;
  padding-top: 0;
  padding-bottom: 0;
}
.input-new-tag {
  width: 90px;
  margin-left: 10px;
  vertical-align: bottom;
}
</style>
